package interfaces.lunchy;




import java.util.Iterator;
import java.util.List;
import java.util.Properties;


import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;



public class Hibernate implements DAO{

	private static SessionFactory factory;

	public Hibernate(){
		try{
			Configuration cfg = new Configuration();
			cfg.setProperties(getPropertyConfiguration());
		    
		    mappingAnnotatedClasses(cfg);
		    
		    
		    ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry();
			factory = cfg.buildSessionFactory(serviceRegistry);
		}catch (Throwable ex) { 
			System.err.println("Failed to create sessionFactory object." + ex);
			throw new ExceptionInInitializerError(ex); 
		}
	}

	private void mappingAnnotatedClasses(Configuration cfg) {
		cfg.setProperties(getPropertyConfiguration());
		cfg.addAnnotatedClass(Property.class);
		cfg.addAnnotatedClass(Client.class);
		cfg.addAnnotatedClass(Dish.class);
		cfg.addAnnotatedClass(Category.class);
		cfg.addAnnotatedClass(Order.class);
	}

	private Properties getPropertyConfiguration() {
		Properties propHibernatemapping = new Properties();
		propHibernatemapping.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
		propHibernatemapping.setProperty("hibernate.connection.driver_class", "org.postgresql.Driver");
		propHibernatemapping.setProperty("hibernate.connection.url", "jdbc:postgresql://127.0.0.1:5432/bd"); 
		propHibernatemapping.setProperty("hibernate.connection.username", "postgres");
		propHibernatemapping.setProperty("hibernate.connection.password", "postgrespass");
		propHibernatemapping.setProperty("hibernate.connection.pool_size", "5");
		propHibernatemapping.setProperty("hibernate.connection.autocommit", "false");
		propHibernatemapping.setProperty("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
		propHibernatemapping.setProperty("hibernate.hbm2ddl.auto", "update");
		propHibernatemapping.setProperty("hibernate.show_sql", "true");
		propHibernatemapping.setProperty("hibernate.format_sql","true");
		propHibernatemapping.setProperty("hibernate.use_sql_comments","true");
		propHibernatemapping.setProperty("hibernate.transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory");
		propHibernatemapping.setProperty("hibernate.current_session_context_class", "thread");
		propHibernatemapping.setProperty("org.hibernate.flushMode", "COMMIT");
		propHibernatemapping.setProperty("hibernate.generate_statistics", "true");
		return propHibernatemapping;
	}

	@Override
	public void addCategory(String nameCategory) throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public void clearOrder(Order order) throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean deleteCategory(String nameCategory) throws Exception {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public Category getCategory(String nameCategory) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<String> getListCategoryMenu() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public LunchMenu getMenu() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getNameActiveClient() throws Exception {
		String nameClient = null;
		Session session = factory.openSession(); 
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
			Property property = (Property) session.get(Property.class, CHECKED_CLIENT);
			nameClient = property.getValue();
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
			e.printStackTrace(); 
		}finally {
			session.close(); 
		}
		return nameClient;
	}

	@Override
	public Order getOrder(String nameClient) throws Exception {
		Order order = new Order();
		order.getClient().setNameClient(nameClient);
		Session session = factory.openSession(); 
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
			Client client = new Client();
			Query query = session.createQuery("FROM Client WHERE name = ?");
			query.setString(0, nameClient);
			Iterator itr = query.iterate();
			while (itr.hasNext()){
				client = (Client) itr.next();
			}
			ItemsOrder items = setItemsOrder(client, session);
			order.setItems(items);
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
			e.printStackTrace(); 
		}finally {
			session.close(); 
		}
		return order;
	}

	private ItemsOrder setItemsOrder(Client client, Session session) {
		Query query = session.createQuery("FROM Order WHERE clientId = ?");
		query.setEntity(0, client);
		List list = query.list();
		ItemsOrder items = new ItemsOrder();
		Iterator itr = list.iterator();
		while (itr.hasNext()){
			Order order = (Order) itr.next();
			items.getDishes().add(order.getDishId().getDish());
			items.getNumberDishes().add(order.getNumber());
		}
		return items;
	}

	@Override
	public String getProperty(String key) throws Exception {
		String value = null;
		Session session = factory.openSession(); 
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
			Property property = (Property) session.get(Property.class, key);
			value = property.getValue();
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
			e.printStackTrace(); 
		}finally {
			session.close(); 
		}
		return value;
	}



	@Override
	public List<String> loadListClient() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean saveListClient(List<String> listClient) throws Exception {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void saveMenu(LunchMenu menu) throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public void saveOrder(Order order) throws Exception {
		/*Session session = factory.openSession(); 
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
			
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
			e.printStackTrace(); 
		}finally {
			session.close(); 
		}
*/
	}

	@Override
	public void setNameActiveClient(String nameClient) throws Exception {
		// TODO Auto-generated method stub

	}




	@Override
	public void setFlagUpdate(String flagUpdate) throws Exception {
		// TODO Auto-generated method stub
		
	}

	@Override
	public String getFlagUpdate() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void setProperty(String key, String value) throws Exception {
		Session session = factory.openSession(); 
		Transaction tx = null;
		try{
			tx = session.beginTransaction();
			Property property = (Property) session.get(Property.class, key);
			property.setValue(value);
			session.update(property);
			tx.commit();
		}catch (HibernateException e) {
			if (tx!=null) tx.rollback();
			e.printStackTrace(); 
		}finally {
			session.close(); 
		}
	}

}
